/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.crop;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;

/**
 * Provides crop data.
 * This will be from a localized module.
 *
 *
 * @author Gerben Feenstra
 */
@ServiceProvider(service = CropService.class)
public class CropService  {

    final private static String GENUS_KEYSTART = "crop.genus.";
    final private static String RACE_KEYSTART = "crop.race.";
    final public List<Crop> crops = new ArrayList<Crop>();
    final public List<Race> races = new ArrayList<Race>();
    
    private ResourceBundle bundle;
    private final String BUNDLE = "nl.cloudfarming.client.crop.Bundle"; //NOI18N
            
    public CropService(){
        bundle = NbBundle.getBundle(BUNDLE, Locale.getDefault());    
        init();  
    }
    
    /**
     * Initialize Crops and Races-lists. Link Crops to Races.
     */
    final public void init(){
        Enumeration<String> bundleKeys = bundle.getKeys();
        
        while(bundleKeys.hasMoreElements()){
            String key = bundleKeys.nextElement();

            if(key.startsWith(GENUS_KEYSTART)){  
                Crop crop = getOrCreateCrop(key);
                setCropProperty(key, crop);
            }
            else if(key.startsWith(RACE_KEYSTART)){
                Crop crop = getOrCreateCrop(key);
                Race race = getOrCreateRace(key, crop);
                race.setCrop(crop);
            }
        }  
    }
      
    /**
     * Extract crop from bundle key, get or create crop.
     * @param key Key to create crop from
     * @return 
     */
    
    protected Crop getOrCreateCrop(String key){              
        // Get existing crop or create a new one.                
        Crop crop = null;
        crop = getCropForKey(key);
        if(crop == null){
            crop = new Crop(getBundleCropName(key));
            if(crop != null){
                crops.add(crop);
            }
        }
        return crop;        
    }
    
    /**
     * Extract race from bundle key, get or create race, set crop this race belongs to.
     * @param key Bundle key of this race
     * @param crop Crop-object to which this race should be linked.
     */    
    protected Race getOrCreateRace(String key, Crop crop){
        Race race = null;
        race = getRaceForKey(key);
        
        if(race == null){
            race = new Race(getBundleRaceName(key));
            if(race != null){
                race.setName(bundle.getString(key));
                races.add(race);
            }
        }

        return race;
    }

    /**
     * Extract crop name from bundle keyname
     * 
     * Format cropname = crop.genus.[cropname].[property] - or -  crop.race.[cropname].[racename]
     * 
     * For example: 
     * 
     * crop.genus.solanum_tuberosum.name - or - crop.race.solanum_tuberosum.bintje
     * 
     * @param key Key to extract name from
     * @return Stripped key = bundle keyname
     */
    protected String getBundleCropName(String key){
        String strippedKey = "";
        
        if(key.startsWith(GENUS_KEYSTART)){
            strippedKey = key.replace(GENUS_KEYSTART, "");
        }
        else if(key.startsWith(RACE_KEYSTART)){
            strippedKey = key.replace(RACE_KEYSTART, "");
        }
        
        int dotPos = strippedKey.indexOf(".");
        if(dotPos > 0){
            return strippedKey.substring(0, dotPos);
        }
        
        return strippedKey;
    }
 
    /**
     * Format race-name = crop.race.[cropname].[racename]
     * For example: crop.race.solanum_tuberosum.bintje
     * 
     * @param key
     * @return Bundlekey Racename
     */
    protected String getBundleRaceName(String key){       
        if(key.startsWith(RACE_KEYSTART)){
            int dotPos = key.lastIndexOf(".")+1;
            if(dotPos > 0){   
                return key.substring(dotPos);
            }
        }
        return "";
    }

    /**
     * Set property as described by the specified key of specified crop
     * 
     * Example: 
     * key = crop.genus.solanum_tuberosum.name
     * then property = name
     * @param key
     * @param crop 
     */
    protected void setCropProperty(String key, Crop crop){
        String value = bundle.getString(key);
        
        StringBuilder toStrip = new StringBuilder();
        toStrip.append(GENUS_KEYSTART);
        toStrip.append(crop.getKeyName());
        toStrip.append(".");
            
        String property = key.replace(toStrip.toString(), "").toLowerCase();

        if(property.equals("name")){
            crop.setName(value);
        }
        else if(property.equals("id")){
            if(value.length() > 0){
                crop.setId(Long.parseLong(value));
            }
        }
        else if(property.equals("governmentalid")){
            if(value.length() > 0){
                crop.setGovernmentalId(Long.parseLong(value));
            }
        }
    }

    /**
     * Retrieve a crop based on its key
     * Will return null if no crop can be found for specified key
     *
     * @param Key
     * @return
     */
    public Crop getCropForKey(String key){
        String keyName = getBundleCropName(key);
        
        for(Crop crop : crops){
            if(crop.getKeyName().equals(keyName)){
                return crop;
            }
        }
        return null;
    }

    /**
     * Retrieve a race based on its key
     * Will return null if no race can be found for specified key
     *
     * @param Key
     * @return
     */
    public Race getRaceForKey(String key){
        String keyName = getBundleRaceName(key);
        
        for(Race race : races){
            if(race.getKeyName().equals(keyName)){
                return race;
            }
        }
        return null;
    }
    
    /**
     * Retrieve a list with all available crops
     *
     * @return A list with all available crops
     */
    public List<Crop> getCrops(){
        return crops;
    }

    /**
     * Get a List of races belonging to the specified Crop.
     * @return 
     */
    public List<Race> getRaces(Crop crop){
        List<Race> raceSelection = new ArrayList<Race>();
        for(Race race : races){
            if(race.getCrop().equals(crop)){
                raceSelection.add(race);
            }
        }
        return raceSelection;
        
    }
}